1 /* 2 * Copyright (C) 2005 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.reflect; 18 19 import static com.google.common.base.Preconditions.checkArgument; 20 import static com.google.common.base.Preconditions.checkNotNull; 21 22 import com.google.common.annotations.Beta; 23 24 import java.lang.reflect.InvocationHandler; 25 import java.lang.reflect.Proxy; 26 27 /** 28 * Static utilities relating to Java reflection. 29 * 30 * @since 12.0 31 */ 32 @Beta 33 public final class Reflection { 34 35 /** 36 * Returns the package name of {@code clazz} according to the Java Language Specification (section 37 * 6.7). Unlike {@link Class#getPackage}, this method only parses the class name, without 38 * attempting to define the {@link Package} and hence load files. 39 */ 40 public static String getPackageName(Class<?> clazz) { 41 return getPackageName(clazz.getName()); 42 } 43 44 /** 45 * Returns the package name of {@code classFullName} according to the Java Language Specification 46 * (section 6.7). Unlike {@link Class#getPackage}, this method only parses the class name, without 47 * attempting to define the {@link Package} and hence load files. 48 */ 49 public static String getPackageName(String classFullName) { 50 int lastDot = classFullName.lastIndexOf('.'); 51 return (lastDot < 0) ? "" : classFullName.substring(0, lastDot); 52 } 53 54 /** 55 * Ensures that the given classes are initialized, as described in 56 * <a href="http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.4.2"> 57 * JLS Section 12.4.2</a>. 58 * 59 * <p>WARNING: Normally it's a smell if a class needs to be explicitly initialized, because static 60 * state hurts system maintainability and testability. In cases when you have no choice while 61 * inter-operating with a legacy framework, this method helps to keep the code less ugly. 62 * 63 * @throws ExceptionInInitializerError if an exception is thrown during 64 * initialization of a class 65 */ 66 public static void initialize(Class<?>... classes) { 67 for (Class<?> clazz : classes) { 68 try { 69 Class.forName(clazz.getName(), true, clazz.getClassLoader()); 70 } catch (ClassNotFoundException e) { 71 throw new AssertionError(e); 72 } 73 } 74 } 75 76 /** 77 * Returns a proxy instance that implements {@code interfaceType} by 78 * dispatching method invocations to {@code handler}. The class loader of 79 * {@code interfaceType} will be used to define the proxy class. To implement 80 * multiple interfaces or specify a class loader, use 81 * {@link Proxy#newProxyInstance}. 82 * 83 * @throws IllegalArgumentException if {@code interfaceType} does not specify 84 * the type of a Java interface 85 */ 86 public static <T> T newProxy( 87 Class<T> interfaceType, InvocationHandler handler) { 88 checkNotNull(handler); 89 checkArgument(interfaceType.isInterface(), "%s is not an interface", interfaceType); 90 Object object = Proxy.newProxyInstance( 91 interfaceType.getClassLoader(), 92 new Class<?>[] { interfaceType }, 93 handler); 94 return interfaceType.cast(object); 95 } 96 97 private Reflection() {} 98 }